#!/usr/bin/env python3
import sys

from scapy.all import (
    Ether,
    IPOption,
    Packet,
    bind_layers,
    get_if_list,
    sniff,
    IP,
    TCP,
    UDP,
    FieldLenField,
    FieldListField,
    IntField,
    ShortField
)
from scapy.fields import *
from scapy.layers.inet import _IPOption_HDR


def get_if():
    ifs=get_if_list()
    iface=None
    for i in get_if_list():
        if "eth0" in i:
            iface=i
            break;
    if not iface:
        print("Cannot find eth0 interface")
        exit(1)
    return iface

class IPOption_MRI(IPOption):
    name = "MRI"
    option = 31
    fields_desc = [ _IPOption_HDR,
                    FieldLenField("length", None, fmt="B",
                                  length_of="swids",
                                  adjust=lambda pkt,l:l+4),
                    ShortField("count", 0),
                    FieldListField("swids",
                                   [],
                                   IntField("", 0),
                                   length_from=lambda pkt:pkt.count*4) ]
def handle_pkt(pkt):
    if IP in pkt:
        if TCP in pkt and pkt[TCP].dport == 1234:
            print("Received an IPv4 TCP packet:")
            pkt.show2()
        elif UDP in pkt and pkt[UDP].dport == 4321:
            print("Received a source routed packet:")
            pkt.show2()
        else:
            print("Received an IP packet with unknown transport:")
            pkt.show2()
sys.stdout.flush()

class SourceRoute(Packet):
   fields_desc = [ BitField("bos", 0, 1),
                   BitField("port", 0, 15)]
class SourceRoutingTail(Packet):
   fields_desc = [ XShortField("etherType", 0x800)]

bind_layers(Ether, SourceRoute, type=0x1234)
bind_layers(SourceRoute, SourceRoute, bos=0)
bind_layers(SourceRoute, SourceRoutingTail, bos=1)

def main():
    iface = get_if()
    print("Sniffing on %s" % iface)
    sys.stdout.flush()
    sniff(iface=iface, prn=handle_pkt)

if __name__ == '__main__':
    main()
